<template>
  <h1 class="m-v-30">侦听器</h1>

  <div>
    加一getter获取<button @click="count++,x++">{{count}}</button><br>
    不能直接侦听响应式对象的属性值，通过返回值侦听<br>
    <button @click="obj.count++">{{obj.count}}</button><br>
    第一个参数传入对象会创建一个深层侦听器
    {{obj.count}}---{{obj.index}}
  </div>

  <h3 class="m-v-10">
    wtchEffect()
  </h3>
  <div>
    1. watch是懒执行的：仅当数据源变化时才会执行，<br>
    2. watchEffect初始数据，并在数据变化时会立即执行<br>
  </div>

  <h3 class="m-v-10">watch VS watchEffect</h3>
  <div>
    1. watch 只追踪明确侦听的数据源。它不会追踪任何在回调中访问到的东西。另外，仅在数据源确实改变时才会触发回调。watch 会避免在发生副作用时追踪依赖，因此，我们能更加精确地控制回调函数的触发时机。
    2. watchEffect，则会在副作用发生期间追踪依赖。它会在同步执行过程中，自动追踪所有能访问到的响应式属性。这更方便，而且代码往往更简洁，但有时其响应性依赖关系会不那么明确。
  </div>

  <h3 class="m-v-10">回调触发的时机</h3>
  <div>
    默认情况下，用户创建的侦听器回调，都会在 Vue 组件更新之前被调用。这意味着你在侦听器回调中访问的 DOM 将是被 Vue 更新之前的状态。如果想在侦听器回调中能访问被 Vue 更新之后的DOM，你需要指明 flush: 'post'
  </div>
  <!-- <button @click="active=true">显示被隐藏的DOM</button> -->
  <div v-show="active"
    ref="activeDom">显示被隐藏的DOM</div>

  <h3 class="m-v-10">停止侦听</h3>
  <div>
    1. 同步语句创建的侦听器会在组建销毁时自动停止，但是异步创建的不会需要手动停止以防止内存泄漏<br>
    2. <button @click="stopWatch">
      停止侦听器
    </button>
  </div>
</template>

<script setup>
import { reactive, ref } from "@vue/reactivity";
import { watch, watchEffect } from "@vue/runtime-core";


let count = ref(0)

let x = ref(1)
let y = ref(2)
let active = ref(false)

const activeDom = ref()

let obj = reactive({ count: 22, index: 0 })

watch(count, (newValue, oldValue) => {
  console.log(newValue, oldValue);
})

watch(() => x.value + y.value, (newValue) => {
  console.log('sum=', newValue)
})


watch(() => obj.count, (newValue) => {
  console.log('对象的属性改变了：', newValue);
})

watch(obj, (newValue) => {
  console.log('对象更新了：', newValue);
  active.value = newValue.count > 22 ? true : false
  console.log('访问DOM', activeDom.value);
}, { flush: 'post' })


// let unwatch = watchEffect(() => {
//   console.log('立即执行', obj.count);
// })

let unwatch
setTimeout(() => {
  unwatch = watchEffect(() => {
    console.log('立即执行', obj.count);
  })
}, 1000)


function stopWatch() {
  unwatch()
}




</script>

<style lang="scss" scoped>
</style>